package controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JDialog;

import org.apache.commons.beanutils.BeanUtils;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import util.HibernateUtil;
import view.SearchBookPage;
import bean.Catalog;
import dto.BookDTO;
import dto.LogonDTO;
import dto.SearchBookDTO;

public class SearchBookController {

	private SearchBookPage searchBook;

	private EditBookController editController;
	private ViewBookController viewController;
	private DeleteBookController deleteController;

	private SearchBookDTO searchDTO;

	void searchForBook(LogonDTO logonDTO, String mode) {

		searchBook = new SearchBookPage(logonDTO, mode);

		searchBook.addSearchBookButtonListener(new SearchBookListener(mode));

		searchBook.setModal(true);
		searchBook.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		searchBook.setVisible(true);

	}

	class SearchBookListener implements ActionListener {

		private String mode;

		SearchBookListener(String mode) {
			this.mode = mode;
		}

		public void actionPerformed(ActionEvent arg0) {
			editController = new EditBookController();
			deleteController = new DeleteBookController();

			searchDTO = searchBook.getSearchBookDTO();
			List<BookDTO> books = new ArrayList<BookDTO>();

			// no checkbox is selected
			if (!searchDTO.isCheckedTitle() && !searchDTO.isCheckedAuthor()
					&& !searchDTO.isCheckedCatalogNo()
					&& !searchDTO.isCheckedISBN()) {
				searchBook.displayMessage("No search criteria selected.");
			} else {

				List<Catalog> searchResult = searchDatabase();

				for (Catalog catalog : searchResult) {

					BookDTO bookDTO = new BookDTO();

					try {
						BeanUtils.copyProperties(bookDTO, catalog.getBook());
						bookDTO.setDeweyDecimalNo(catalog.getDeweyDecimalNo());
						bookDTO.setOnLoan(catalog.getOnLoan());
						bookDTO.setRemarks(catalog.getRemarks());

					} catch (IllegalAccessException e) {
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						e.printStackTrace();
					}

					books.add(bookDTO);
				}

				searchBook.setSearchedBooks(books);

				searchBook.reDrawThis(new ActionListener() {

					public void actionPerformed(ActionEvent arg0) {
						int index = Integer.parseInt(arg0.getActionCommand());

						if (mode == "EDIT")
							editController.editBook(searchBook.getLogonDTO(),
									searchBook.getSearchedBooks().get(index));
						else
							viewController.viewBook(searchBook.getLogonDTO(),
									searchBook.getSearchedBooks().get(index));
					}
				}, deleteController.new DeleteBookListener(searchBook));

				searchBook.displayMessage("Found " + books.size()
						+ " match(es).");
			}
		}
	}

	private List<Catalog> searchDatabase() {

		List<Catalog> searchResult = new ArrayList<Catalog>();

		String queryString = null;
		String title = searchDTO.getTitle();
		String author = searchDTO.getAuthor();
		String ddc = searchDTO.getDeweyDecimalNo();
		String ISBN = searchDTO.getISBN();

		if (searchDTO.isCheckedTitle() && searchDTO.isCheckedAuthor()) {
			// search by title and author
			queryString = "SELECT c FROM Catalog c LEFT JOIN FETCH c.book WHERE c.book.title LIKE '%"
					+ title + "%' AND c.book.author LIKE '%" + author + "%'";

		} else if (searchDTO.isCheckedTitle()) {
			// search by title only
			queryString = "SELECT c FROM Catalog c LEFT JOIN FETCH c.book WHERE c.book.title LIKE '%"
					+ title + "%'";

		} else if (searchDTO.isCheckedAuthor()) {
			// search by author only
			queryString = "SELECT c FROM Catalog c LEFT JOIN FETCH c.book WHERE c.book.author LIKE '%"
					+ author + "%'";

		} else if (searchDTO.isCheckedCatalogNo()) {
			// search by catalog only
			queryString = "SELECT c FROM Catalog c LEFT JOIN FETCH c.book WHERE c.deweyDecimalNo = '"
					+ ddc + "'";

		} else if (searchDTO.isCheckedISBN()) {
			// search by ISBN only
			queryString = "SELECT c FROM Catalog c LEFT JOIN FETCH c.book WHERE c.book.ISBN = '"
					+ ISBN + "'";

		}

		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
		Session session = sessionFactory.openSession();

		Query query = session.createQuery(queryString);

		List catalogList = query.list();
		if (!catalogList.isEmpty()) {
			for (int i = 0; i < catalogList.size(); i++) {
				Catalog catalog = (Catalog) catalogList.get(i);
				searchResult.add(catalog);
			}
		}

		return searchResult;
	}

}
